package disjunction
{
	import disjunction.GameState;
	import disjunction.View;
	import disjunction.state.StateChangeEvent;
	import disjunction.timing.SimulationTimer;
	
	import flash.events.TimerEvent;

	/**
	 * The Controller in the context of the (MVC) GameState. Provides a configurable
	 * base for timing and updates. Actual control logic is handled through injected
	 * strategies.
	 * 
	 * @author Nick Wiggill
	 */

	public class Controller extends TimedUpdater
	{
		/** 
		 * The model pertaining to this Controller. Since only the parent controller
		 * has a reference to this, there is no problem with it being public.
		 */
		public var model:Object;
		public var view:View;
		
		/**
		 * Framework initialisation of the controller and model given appropriate data.
		 * @param config The configuration for the controller itself. Typically describes 
		 * the rate at which various aspects of the model execute.
		 */
		public function initialise_(controllerConfig:ControllerConfig, modelConfig:Object):void
		{
			super.initialiseTiming(controllerConfig as TimingConfig);

			trace('calling controller to initialise');
			initialise(modelConfig); //subclass (user) initialisation

			if (isRealTime)
				start();
		}
		
		/** (abstract) User initialisation of controller and model.*/
		public function initialise(modelConfig:Object):void
		{
		}
		
		//call this as super AFTER your custom logic.
		protected override function update(timeDeltaMs:uint):void
		{
			//only process if we have entity lists to access.
			if (model is IEntityListModel)
			{
				var model_:IEntityListModel = model as IEntityListModel;
				var entity:Object;
				
				//remove
				for each (entity in model_.toRemove)
				{
					model_.current.splice(model_.current.lastIndexOf(entity, 0), 1);
					view.removeEntity(entity);
				}
				//add
				for each (entity in model_.toAdd)
				{
					model_.current.push(entity);
					view.addEntity(entity);			
				}
				//clear both temp lists.
				model_.toRemove.splice(0, model_.toRemove.length);
				model_.toAdd.splice(0, model_.toAdd.length);
			}
		}	
	}
}